﻿using MiniFox.Infrastructure;
using MiniFox.Security;
using System;
using System.Globalization;

namespace MiniFox.Platform.OAuth2
{
    /// <summary>
    /// 通行证令牌
    /// </summary>
    public class PassportToken : Ticket
    {
        /// <summary>
        /// 用于保存全局令牌票据的键名
        /// </summary>
        public const string OPEN_AUTH_TICKET = @"minifox-oauth2-passport-ticket";
        DateTimeOffset _renewTime;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ticketId"></param>
        internal PassportToken(string ticketId) : this(ticketId, 3600)
        {

        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ticketId"></param>
        /// <param name="duration"></param>
        public PassportToken(string ticketId, int duration) : this(ticketId, DateTimeOffset.Now, DateTimeOffset.Now, duration)
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ticketId"></param>
        /// <param name="creationTime"></param>
        /// <param name="renewTime"></param>
        /// <param name="duration"></param>
        private PassportToken(string ticketId, DateTimeOffset creationTime, DateTimeOffset renewTime, int duration) : base(ticketId, creationTime, duration)
        {
            _renewTime = renewTime;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ticketId"></param>
        /// <param name="creationTime"></param>
        /// <param name="renewTime"></param>
        /// <param name="duration"></param>
        /// <returns></returns>
        public static PassportToken Create(string ticketId, DateTimeOffset creationTime, DateTimeOffset renewTime, int duration)
        {
            return new PassportToken(ticketId, creationTime, renewTime, duration);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            string[] array = {
                 this.TicketID,
                this.CreationTime.ToString(GlobalStandardFormat.COMPLETE_DATETIME_OFFSET_FORMAT),
                this.Duration.ToString(),
                this.RenewTime.ToString(GlobalStandardFormat.COMPLETE_DATETIME_OFFSET_FORMAT)
            };
            string token = string.Join(SPLITER.ToString(), array);
            return token.DesEncrypt();
        }

        /// <summary>
        /// 
        /// </summary>
        public DateTimeOffset RenewTime
        {
            get { return _renewTime; }
        }
        /// <summary>
        /// 
        /// </summary>
        public override DateTimeOffset ExpiredTime
        {
            get { return RenewTime.AddSeconds(this.Duration); }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public static implicit operator PassportToken(string token)
        {
            if (string.IsNullOrEmpty(token))
                return null;
            string t = token.DesDecrypt();
            string[] datas = t.Split(SPLITER);
            string ticketId = datas[0];
            var creationTime = DateTimeOffset.ParseExact(datas[1], GlobalStandardFormat.COMPLETE_DATETIME_OFFSET_FORMAT, CultureInfo.CurrentCulture.DateTimeFormat, DateTimeStyles.None);
            int duration = int.Parse(datas[2]);
            var renewTime = DateTimeOffset.ParseExact(datas[3], GlobalStandardFormat.COMPLETE_DATETIME_OFFSET_FORMAT, CultureInfo.CurrentCulture.DateTimeFormat, DateTimeStyles.None);
            PassportToken passportToken = Create(ticketId, creationTime, renewTime, duration);
            return passportToken;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            if (obj == null)
                return false;
            if (obj is PassportToken)
            {
                PassportToken token = obj as PassportToken;
                return this.TicketID == token.TicketID && this.CreationTime == token.CreationTime;
            }
            else if (obj is string)
            {
                string t1 = this;
                string t2 = obj as string;
                return t1 == t2;
            }
            else
            {
                throw new InvalidCastException();
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="token1"></param>
        /// <param name="token2"></param>
        /// <returns></returns>
        public static bool operator ==(PassportToken token1, PassportToken token2)
        {
            return object.Equals(token1, token2);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="token1"></param>
        /// <param name="token2"></param>
        /// <returns></returns>
        public static bool operator !=(PassportToken token1, PassportToken token2)
        {
            return !object.Equals(token1, token2);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="passportToken"></param>
        /// <returns></returns>
        public static implicit operator string(PassportToken passportToken)
        {
            if (passportToken == null)
                return null;
            return passportToken.ToString();
        }
        /// <summary>
        /// 刷新
        /// </summary>
        public virtual void Renew()
        {
            this._renewTime = DateTimeOffset.Now;
        }
    }
}
